/**
 * 
 */
package sailing.ui.progressdialog;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.plaf.metal.MetalScrollPaneUI;

import org.jdesktop.application.SingleFrameApplication;

import sailing.ui.base.AbstractJDialog;
import sailing.worker.FileIOWorker;
import cjlite.logger.Logger;

import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;
import com.sun.java.swing.plaf.windows.WindowsTextAreaUI;

/**
 * @author kevin
 * 
 */
public class ProgressDialog extends AbstractJDialog {

	private static Logger logger = Logger.thisClass();
	private String dialogMsg = "";
	private JLabel msgLabel, taskLabel;
	private JTextArea taskInfoTA;

	private JProgressBar progressBar;
	private JButton cancelBtn;
	private JButton okBtn;

	private static String newLine = "\r\n";

	private FileIOWorker fileworker;

	private ProgressDialog(String title, Window window, SingleFrameApplication singleFrameApplication) {
		super(window, title, ModalityType.APPLICATION_MODAL, singleFrameApplication);
		this.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
	}

	private void initialDialog() {
		// JPanel all = new FormDebugPanel(true, true);
		JPanel all = new JPanel();
		all.setBorder(BorderFactory.createEmptyBorder(20, 50, 30, 50));

		FormLayout layout = new FormLayout("f:230dlu,f:50dlu,f:5dlu,f:50dlu",
				"22dlu,6dlu,12dlu,6dlu,f:110dlu,8dlu,22dlu");
		all.setLayout(layout);
		CellConstraints cc = new CellConstraints();
		// row 1
		msgLabel = new JLabel();
		// msgLabel.setText(this.dialogMsg);
		// msgLabel.setText("============msgLabel=================");
		all.add(msgLabel, cc.xywh(1, 1, 4, 1));

		// row 3
		progressBar = new JProgressBar(JProgressBar.HORIZONTAL, 0, 100) {
			public Dimension getPreferredSize() {
				return new Dimension(400, 30);
			}
		};

		all.add(progressBar, cc.xywh(1, 3, 4, 1));

		// row 5
		taskInfoTA = new JTextArea(7, 70);
		taskInfoTA.setEditable(false);
		// WindowsTextUI
		taskInfoTA.setUI(new WindowsTextAreaUI());
		// taskLabel.setText(this.dialogMsg);
		// taskLabel.setText("===========taskLabel================");
		JScrollPane sp = new JScrollPane(taskInfoTA);
		// sp.setUI(new WindowsScrollPaneUI());
		sp.setUI(new MetalScrollPaneUI());
		sp.setBackground(this.getBackground());
		all.add(sp, cc.xywh(1, 5, 4, 1));

		// row 7
		cancelBtn = new JButton();
		cancelBtn.setText("取消");
		cancelBtn.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				confirmToCloseWindow();
			}
		});
		all.add(cancelBtn, cc.xy(2, 7));
		// row 7
		okBtn = new JButton();
		okBtn.setText("确定");
		okBtn.setEnabled(false);
		okBtn.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				confirmToCloseWindow();
			}
		});
		all.add(okBtn, cc.xy(4, 7));

		this.setLayout(new BorderLayout());
		this.add(all, BorderLayout.CENTER);
		this.pack();
	}

	/**
	 * for future remove JGoodies Form Layout used.
	 */
	private void initialDialog_back() {
		// All box
		Box all = Box.createVerticalBox();
		all.setBorder(BorderFactory.createEmptyBorder(30, 50, 40, 50));
		// msg label
		msgLabel = new JLabel();
		// msgLabel.setText(this.dialogMsg);
		msgLabel.setText("============msgLabel=================");
		all.add(msgLabel);
		all.add(Box.createVerticalStrut(30));
		// task message
		taskLabel = new JLabel();
		// taskLabel.setText(this.dialogMsg);
		taskLabel.setText("===========taskLabel================");
		all.add(taskLabel);
		all.add(Box.createVerticalStrut(30));

		//
		progressBar = new JProgressBar(JProgressBar.HORIZONTAL) {
			public Dimension getPreferredSize() {
				return new Dimension(400, 30);
			}
		};
		all.add(progressBar);
		all.add(Box.createVerticalStrut(30));

		Box hbox = Box.createVerticalBox();
		hbox.add(Box.createHorizontalGlue());
		cancelBtn = new JButton();
		cancelBtn.setText("取消");
		hbox.add(cancelBtn);
		all.add(hbox);

		// add bottom space
		all.add(Box.createVerticalStrut(50));

		this.setLayout(new BorderLayout());
		this.add(all, BorderLayout.CENTER);
		this.pack();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.awt.Dialog#isResizable()
	 */
	@Override
	public boolean isResizable() {
		return false;
	}

	/**
	 * @param title
	 *            Dialog Title
	 * @param componenet
	 *            current JComponent which used to popup this ProgressDialog
	 * @param singleFrameApplication
	 *            Application
	 * @return
	 * @throws Exception
	 */
	public static ProgressDialog loadDialog(String title, JComponent component,
			SingleFrameApplication singleFrameApplication) throws Exception {
		Window window = SwingUtilities.getWindowAncestor(component);

		if (window == null) {
			logger.error("the componenet[{0}] has no window, it should have", component.toString());
		}

		return new ProgressDialog(title, window, singleFrameApplication);
	}

	public static void main(String[] arg) {
		ProgressDialog pd = new ProgressDialog("test", null, null);
		pd.setVisible(true);
	}

	public void setTaskMsg(String msg) {

	}

	@Override
	protected void initialUI() {
		initialDialog();
		this.addWindowListener(new WindowAdapter() {
			/*
			 * (non-Javadoc)
			 * 
			 * @see java.awt.event.WindowAdapter#windowClosing(java.awt.event.WindowEvent)
			 */
			@Override
			public void windowClosing(WindowEvent e) {
				logger.trace("new state={0}, old state={1}", e.getNewState(), e.getOldState());
				confirmToCloseWindow();
				super.windowClosing(e);
			}

			/*
			 * (non-Javadoc)
			 * 
			 * @see java.awt.event.WindowAdapter#windowClosed(java.awt.event.WindowEvent)
			 */
			@Override
			public void windowClosed(WindowEvent e) {
				logger.trace("new state={0}, old state={1}", e.getNewState(), e.getOldState());
				super.windowClosed(e);
			}

			/*
			 * (non-Javadoc)
			 * 
			 * @see java.awt.event.WindowAdapter#windowStateChanged(java.awt.event.WindowEvent)
			 */
			@Override
			public void windowStateChanged(WindowEvent e) {
				logger.trace("new state={0}, old state={1}", e.getNewState(), e.getOldState());
				super.windowStateChanged(e);
			}

			/*
			 * (non-Javadoc)
			 * 
			 * @see java.awt.event.WindowAdapter#windowOpened(java.awt.event.WindowEvent)
			 */
			@Override
			public void windowOpened(WindowEvent e) {
				startToProcessFileWorker();
			}

		});
	}

	protected void startToProcessFileWorker() {
		String msg = this.fileworker.getWorkerMsg();
		this.msgLabel.setText(msg);
		this.fileworker.setProgressDialog(this);
		this.fileworker.execute();
	}

	protected void confirmToCloseWindow() {
		logger.entry();
		if (fileworker.isDone()) {
			this.setVisible(false);
		} else {
			int result = JOptionPane.showConfirmDialog(this, fileworker.getTerminationMsg(), "警告！",
					JOptionPane.YES_NO_OPTION);
			if (JOptionPane.YES_OPTION == result) {
				fileworker.terminate();
				this.setVisible(false);
			}
		}
	}

	public void setFileWorker(FileIOWorker flw) {
		this.fileworker = flw;
	}

	public void appendTaskMsg(String msg) {
		this.taskInfoTA.append(msg);
		this.taskInfoTA.append(newLine);
	}

	public void setProgress(int progress) {
		this.progressBar.setValue(progress);
		if (progress == 100) {
			this.okBtn.setEnabled(true);
		}
	}

}
